Specs2で嵌っていた話
概要
Scalaでマルチスレッド的なアプリケーションを作っていた。
テストしつつ。
で、今回はSpecs2を使ってるので、
"testCollection" should in {
"test1" in {
...
}
"test2" in {
...
}
"test3" in {
...
}
}
みたいに書いてた。
事象
あるテストを、バリエーション含めて3件書いていた時、
各テストの有無によって結果が変わる。
まーきっと自分たちのバグだろーと思ってまとめつつ、下記のようにケースを書き出した。
テストしていた対象は、
・Actorを内包したクラスで、タイムアウトを指定/指定せず動作
・テストケースではwaitをかけて、起動→動作が終わったかなーっていう時間まで待つ→待機解いてチェック
ということを行っていた。
1 タイムアウト無し
+
2 タイムアウトあり時間内に終了
で問題が出る?→違った
1 タイムアウト無し
+
3 タイムアウトあり
で問題がでる?→違った
1 タイムアウト無し
+
2 タイムアウトあり時間内に終了
+
3 タイムアウトあり
で1,2がRunningで停まる(1,3だったり、2,3だったりランダムな事があとで判明する)
→ただ単に時間がかかる系?違うな。必ず、ってのがおかしい。
→内容について調べてみると、別インスタンスのはずの、各テストケースのクラス中のvarが更新されてしまう、というのが原因だった
なんでこんな事が?
最終的に
→Threadの止め方の問題だった。
Specs2は、非同期のテストを書きたい場合は、そのまま、
Thread.sleep(long)
で、待てば良いのだった。
このへん、待つ機能を独自に作って使い回してたのが判明(Actor側に同期通信投げてActor内でThread.sleep)
穴を掘って穴に嵌った形。
値が同期したのは、単純に「システムの一部がロックして、値が変わらなかった」のを誤って観測したため。
お粗末!